﻿using Abp.Auditing;
using Abp.Configuration;
using Abp.Dependency;
using Abp.Logging;
using Abp.Modules;
using Abp.Settings;
using Castle.MicroKernel.Registration;
using Exceptionless;
using MyCompanyName.AbpZeroTemplate;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Abp
{
    //[DependsOn(typeof(AbpZeroTemplateCoreModule))]
    public class ExceptionlessModule : AbpModule
    {
        public override void Initialize()
        {
            //手工注册 ExceptionlessSettingProvider 等，否则 引发 No component for supporting the service Abp.Settings.ExceptionlessSettingPro
            IocManager.RegisterAssemblyByConvention(typeof(ExceptionlessModule).Assembly);


            base.Initialize();


        }

        public override void PreInitialize()
        {
            this.Configuration.Settings.Providers.Add<ExceptionlessSettingProvider>();

            if (IocManager.IsRegistered<IAuditingStore>())
            {
                var reg = new ComponentRegistration<IAuditingStore>(typeof(ExceptionlessAuditingStore));
                IocManager.IocContainer.Kernel.Register(reg);
            }
            else
            {
                IocManager.Register<IAuditingStore, ExceptionlessAuditingStore>(DependencyLifeStyle.Singleton);
            }
            base.PreInitialize();
        }

        public override void PostInitialize()
        {
            base.PostInitialize();
            PostInitializeExceptionless();
        }

        private void PostInitializeExceptionless()
        {
            ISettingManager settingManager = IocManager.Resolve<ISettingManager>();
            var settings = settingManager.GetAllSettingValues();
            string prefix = $"{nameof(Exceptionless)}.";
            var cfg = ExceptionlessClient.Default.Configuration;
            var listData = settings.Where(x => x.Name.StartsWith(prefix))
                .Where(x => !string.IsNullOrEmpty(x.Value))
                .ToList();
            listData
                .ForEach(x =>
                {
                    if (x.Value == null) { return; }
                    string prop = x.Name.Remove(0, prefix.Length);
                    var p = typeof(ExceptionlessConfiguration).GetProperty(prop);
                    if (p == null || !p.CanWrite)
                    {
                        switch (prop)
                        {
                            default:
                                Console.WriteLine($"设置[{x.Name}]无效!");
                                break;
                        }
                        return;
                    }
                    if (p.PropertyType == typeof(string))
                    {
                        p.SetValue(cfg, x.Value);
                    }
                    else if (p.PropertyType.IsValueType)
                    {
                        object val = JsonConvert.DeserializeObject(x.Value, p.PropertyType);
                        p.SetValue(cfg, val);
                    }
                    else
                    {
                        switch (p.Name)
                        {
                            case nameof(cfg.Settings):
                                {
                                    Dictionary<string, string> dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(x.Value);
                                    foreach (var kv in dict)
                                    {
                                        if (kv.Key.StartsWith("@"))
                                            cfg.Settings.Add(kv.Key, kv.Value);
                                    }
                                }
                                break;
                            default:
                                Console.WriteLine($"设置[{x.Name}]无效!");
                                break;
                        }
                    }
                });

            cfg.UseLogger(new ConsoleLogger());
        }
    }
}
